/**
 * Copyright (c) 2006-2007 Berlin Brown and botnode.com/Berlin Research All
 * Rights Reserved
 * 
 * http://www.opensource.org/licenses/bsd-license.php
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer. * Redistributions in binary
 * form must reproduce the above copyright notice, this list of conditions and
 * the following disclaimer in the documentation and/or other materials provided
 * with the distribution. * Neither the name of the Botnode.com (Berlin Brown)
 * nor the names of its contributors may be used to endorse or promote products
 * derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Date: 12/15/2009
 * 
 * Home Page: http://botnode.com/
 * 
 * Contact: Berlin Brown <berlin dot brown at gmail.com>
 * 
 * Also see:
 * http://htmlcleaner.sourceforge.net/doc/org/htmlcleaner/class-use/TagNode.html
 */
package org.bresearch.octane.browse.win;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import org.bresearch.octane.browse.lib.BrowserHandler;
import org.bresearch.octane.browse.utils.SwingWorker;

/**
 */
public class BrowserFrame extends JPanel implements KeyListener {

    /**
     * 
     */
    private static final long serialVersionUID = 535710310815697611L;

    private BrowserHandler browserHandler;

    private JTextField urlField;

    private JTextArea responseArea;

    private JTextField commandField;

    private JButton actionButton;

    private JLabel status;

    private JTextField statusArea;

    /**
     * Constructor for ConnectFrame.
     * 
     * @param url
     *            JTextField
     * @param response
     *            JTextArea
     * @param actionButton
     *            JButton
     */
    public BrowserFrame(final BrowserHandler handler, final JTextField url, final JTextArea response, final JTextField command,
            final JButton actionButton) {

        this.browserHandler = handler;
        this.urlField = url;
        this.responseArea = response;
        this.commandField = command;
        this.actionButton = actionButton;

        // continue with object construction using setter injection
        // and init validation.
    }

    /**
     * Assert if the object is created properly.
     */
    public void init() {

        // Assert only the aux components.
        if (this.status == null) {
            throw new IllegalStateException("BrowserFrame : Invalid status component.");
        }

    }

    /**
     * Build the status and label component with JPanel. This group is composed
     * of the GridBagLayout.
     * 
     * @return
     */
    public Component buildStatusComponent() {

        // Place the components on one line //
        final JLabel label = new JLabel("Messages: ", JLabel.LEFT);
        final GridBagLayout layout = new GridBagLayout();
        final GridBagConstraints constraints = new GridBagConstraints();
        final JPanel group = new JPanel(layout);
        group.setAlignmentX(JComponent.LEFT_ALIGNMENT);

        constraints.anchor = GridBagConstraints.WEST;
        constraints.gridy = 0;
        constraints.gridx = 0;
        // Specifies how to distribute extra horizontal space.
        constraints.weightx = 0;
        constraints.fill = GridBagConstraints.NONE;
        group.add(label, constraints);

        // Continue to next component
        constraints.gridx = 1;
        constraints.weightx = 1;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        group.add(this.statusArea, constraints);

        return group;
    }

    /**
     * Method loadFrame.
     */
    public void loadFrame() {
        
        this.responseArea.addKeyListener(this);
        final GridBagLayout layout = new GridBagLayout();
        final GridBagConstraints constraints = new GridBagConstraints();

        // Fill the next element, left right
        constraints.anchor = GridBagConstraints.WEST;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.gridx = 0;
        constraints.gridy = 0;
        
        this.setLayout(layout);
        this.add(this.urlField, constraints);

        // Build a scrollable pane around the text area //
        final JScrollPane jScrollPane = new JScrollPane(this.responseArea);

        // For the response area, fill the element, both left/right, up/down.
        constraints.fill = GridBagConstraints.BOTH;
        constraints.gridy++;
        this.add(jScrollPane, constraints);

        constraints.gridy++;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        this.add(this.commandField, constraints);

        constraints.gridy++;
        constraints.anchor = GridBagConstraints.WEST;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        this.add(this.buildStatusComponent(), constraints);

        constraints.gridy++;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        this.add(this.status, constraints);

        constraints.gridy++;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        this.add(this.actionButton, constraints);

        // /////////////////////////////
        // Add the button handler //
        // /////////////////////////////
        final ActionListener connectListener = new ActionListener() {
            public void actionPerformed(final ActionEvent event) {
                final SwingWorker worker = BrowserFrame.this.browserHandler.buildConnectWorker();
                worker.start();
            }}; // End of the Method //
        this.actionButton.addActionListener(connectListener); 
        this.urlField.addActionListener(connectListener);
                
        // /////////////////////////////
        // Add command field handler
        // /////////////////////////////
        this.commandField.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent event) {
                final SwingWorker worker = BrowserFrame.this.browserHandler.buildCommandWorker();
                worker.start();
            } // End of the Method //

        }); // End of Listener //                    
    }
    
    /** Handle the key typed event from the text field. */
    public void keyTyped(KeyEvent e) {           
    }

    /** Handle the key pressed event from the text field. */
    public void keyPressed(KeyEvent e) {
        
        final int keyCode = e.getKeyCode();
        
        if (keyCode == KeyEvent.VK_LEFT) {
            System.out.println("<Key Press, Go Back>");
            final SwingWorker worker = BrowserFrame.this.browserHandler.buildConnectWorkerPrev();
            worker.start();

        } else if (keyCode == KeyEvent.VK_UP) {
            
            System.out.println("<Key Press, Cycle Through Saved Links (up)>");
            
        } else if (keyCode == KeyEvent.VK_DOWN) {
            
            System.out.println("<Key Press, Cycle Through Saved Links (down)>");
            
        } // End of the if - else // 
    }

    /** Handle the key released event from the text field. */
    public void keyReleased(KeyEvent e) {        
    }
    
    /**
     * @return the urlField
     */
    public JTextField getUrlField() {
        return urlField;
    }

    /**
     * @return the responseArea
     */
    public JTextArea getResponseArea() {
        return responseArea;
    }

    /**
     * @return the actionButton
     */
    public JButton getActionButton() {
        return actionButton;
    }

    /**
     * @return the commandField
     */
    public JTextField getCommandField() {
        return commandField;
    }

    /**
     * @param commandField
     *            the commandField to set
     */
    public void setCommandField(JTextField commandField) {
        this.commandField = commandField;
    }

    /**
     * @return the status
     */
    public JLabel getStatus() {
        return status;
    }

    /**
     * @param status
     *            the status to set
     */
    public void setStatus(JLabel status) {
        this.status = status;
    }

    /**
     * @param urlField
     *            the urlField to set
     */
    public void setUrlField(JTextField urlField) {
        this.urlField = urlField;
    }

    /**
     * @param responseArea
     *            the responseArea to set
     */
    public void setResponseArea(JTextArea responseArea) {
        this.responseArea = responseArea;
    }

    /**
     * @param actionButton
     *            the actionButton to set
     */
    public void setActionButton(JButton actionButton) {
        this.actionButton = actionButton;
    }

    /**
     * @return the statusArea
     */
    public JTextField getStatusArea() {
        return statusArea;
    }

    /**
     * @param statusArea
     *            the statusArea to set
     */
    public void setStatusArea(JTextField statusArea) {
        this.statusArea = statusArea;
    }

       
} // End of the Class //
